import type { CrudFilters, CrudSorting } from "@refinedev/core";
import { SysRole, SysSetting } from "@sker/model";
import { useAxiosWebGet, useModel, useModelTable } from "@sker/sdk";
import { useEffect, useState } from "react";
import { Subject } from "rxjs";

export function useSubject(init: (sub: Subject<any>) => void) {
    const [sub, setSub] = useState<Subject<any>>()
    useEffect(() => {
        const sub = new Subject()
        setSub(sub)
        init(sub)
        return () => sub.complete()
    }, [])
    return {
        sub,
        next: (val: any) => sub.next(val),
    }
}

export function useSetting(code: string = `FuliCommonSetting`) {
    const model = useModel(SysSetting)
    const getSetting = () => model.findOne(['code', 'data'], [{ field: 'code', operator: 'eq', value: code }]).then(res => {
        if (res) {
            return res.data;
        }
    })
    const [setting, setSetting] = useState<any>()
    useEffect(() => {
        getSetting().then(res => setSetting(res))
    }, [])
    return {
        setting
    }
}


export function useAddonSetting(name: string = `@fj/core`) {
    const { fetch: getSetting } = useAxiosWebGet('imeepos/core/addon/setting')
    const [setting, setSetting] = useState<any>()
    useEffect(() => {
        getSetting({ name: name }).then(res => setSetting(res.data))
    }, [])
    return {
        setting
    }
}

export interface IOptions {
    table: string;
    primaryType?: string;
    primaryKey?: string;
    title?: string;
    filters?: (params?: any) => Promise<CrudFilters>;
    sorters?: (params?: any) => Promise<CrudSorting>;
    stop?: boolean;
    value?: string;
    selectors?: string[]
}
export function useOptions(config: IOptions) {

    const postage = useModelTable<any>(config.table, config.primaryKey || 'uuid', config.primaryKey || 'id')
    const [data, setData] = useState<any>()
    const [options, setOptions] = useState<any>()
    const [loading, setLoading] = useState<boolean>(false)
    const search = async (params?: any) => {
        setLoading(true)
        const filters = config.filters ? await config.filters(params) : [];
        const sorters = config.sorters ? await config.sorters(params) : [];
        const groups = await postage.findAll([config.title || 'title', config.value || config.primaryKey || 'id', ...(config.selectors || [])], filters, sorters).then(res => res.data)
        const options = groups.map((g: any) => {
            const primaryVal = Reflect.get(g, config.value || config.primaryKey || 'id')
            const primaryTitle = Reflect.get(g, config.title || 'title')
            return { ...g, label: primaryTitle, value: primaryVal }
        })
        setLoading(false)
        return options;
    }
    const get = async (params?: any) => {
        setLoading(true)
        const groupOptions = {}
        const filters = config.filters ? await config.filters(params) : [];
        const sorters = config.sorters ? await config.sorters(params) : [];
        const groups = await postage.findAll([config.title || 'title', config.value || config.primaryKey || 'id', ...(config.selectors || [])], filters, sorters).then(res => res.data)
        groups.map((g: any) => {
            const primaryVal = Reflect.get(g, config.value || config.primaryKey || 'id')
            const primaryTitle = Reflect.get(g, config.title || 'title')
            Reflect.set(groupOptions, primaryVal, primaryTitle)
        });
        setData(groupOptions)
        const options = groups.map((g: any) => {
            const primaryVal = Reflect.get(g, config.value || config.primaryKey || 'id')
            const primaryTitle = Reflect.get(g, config.title || 'title')
            return { ...g, label: primaryTitle, value: primaryVal }
        })
        setOptions(options)
        setLoading(false)
        return options;
    }
    useEffect(() => {
        if (!config.stop) get()
    }, [])
    return {
        data, options, get, model: postage, loading, search
    }
}